package com.enation.app.javashop.core.aftersale.service.impl;

import com.enation.app.javashop.core.aftersale.AftersaleErrorCode;
import com.enation.app.javashop.core.aftersale.model.dos.ClaimsDO;
import com.enation.app.javashop.core.aftersale.model.dos.ExceptionOrderDO;
import com.enation.app.javashop.core.aftersale.model.dto.ExceptionOrderDTO;
import com.enation.app.javashop.core.aftersale.model.enums.*;
import com.enation.app.javashop.core.aftersale.model.vo.*;
import com.enation.app.javashop.core.aftersale.service.ClaimsManager;
import com.enation.app.javashop.core.aftersale.service.ExceptionOrderManager;
import com.enation.app.javashop.core.distribution.service.DistributionManager;
import com.enation.app.javashop.core.member.model.dos.LeaderDO;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.service.LeaderManager;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.promotion.coupon.model.dos.CouponDO;
import com.enation.app.javashop.core.shop.model.dos.Clerk;
import com.enation.app.javashop.core.shop.service.ClerkManager;
import com.enation.app.javashop.core.system.enums.MessageCodeEnum;
import com.enation.app.javashop.core.system.model.dos.MessageTemplateDO;
import com.enation.app.javashop.core.system.service.MessageTemplateManager;
import com.enation.app.javashop.core.trade.order.model.enums.*;
import com.enation.app.javashop.core.trade.order.model.vo.OrderDetailVO;
import com.enation.app.javashop.core.trade.order.service.OrderQueryManager;
import com.enation.app.javashop.core.trade.sdk.model.OrderDetailDTO;
import com.enation.app.javashop.core.trade.sdk.model.OrderSkuDTO;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.security.model.Seller;
import com.enation.app.javashop.framework.util.BeanUtil;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * @author 王志杨
 * @since 2020年9月21日 14:00:50
 * 异常订单业务实现类
 */
@Service
public class ExceptionOrderManagerImpl implements ExceptionOrderManager {

    @Autowired
    @Qualifier("tradeDaoSupport")
    private DaoSupport daoSupport;
    @Autowired
    private ClerkManager clerkManager;
    @Autowired
    private OrderQueryManager orderQueryManager;
    @Autowired
    private MemberManager memberManager;
    @Autowired
    private DistributionManager distributionManager;
    @Autowired
    private LeaderManager leaderManager;
    @Autowired
    private ClaimsManager claimsManager;
    @Autowired
    private MessageTemplateManager messageTemplateManager;
    /**
     * 日志记录
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public Result<ExceptionOrderDTO> insertExceptionOrder(ExceptionOrderDTO exceptionOrderDTO, Seller seller) {
        try {
            //1.参数校验
            Assert.notNull(exceptionOrderDTO, "异常单对象不得为空");
            Assert.notNull(seller, "获取商家登录信息异常");

            //2.获取订单详情并校验订单号
            OrderDetailDTO orderDetailDTO = orderQueryManager.getModel(exceptionOrderDTO.getOrderSn());
            Integer sellerId = seller.getSellerId();
            this.checkOrderAvailability(orderDetailDTO, sellerId);

            //3.订单是否有申请维权校验，是否是强制上报异常，强制上报无需判断
            String serviceStatus = orderDetailDTO.getServiceStatus();
            if (!exceptionOrderDTO.getForceInerst()) {
                Integer count = this.daoSupport.queryForInt("select count(exception_id) from es_exception_order where order_sn=?", orderDetailDTO.getSn());
                if(ServiceStatusEnum.APPLY.value().equals(serviceStatus) && count != null && count > 0){
                    return new Result(ExceptionClaimsCodeEnum.E625.getCode(), ExceptionClaimsCodeEnum.E625.getDescription()
                            .concat("且").concat(ExceptionClaimsCodeEnum.E624.getDescription()));
                }
                if(ServiceStatusEnum.APPLY.value().equals(serviceStatus)) {
                    return new Result(ExceptionClaimsCodeEnum.E625.getCode(), ExceptionClaimsCodeEnum.E625.getDescription());
                }
                if(count != null && count > 0) {
                    return new Result(ExceptionClaimsCodeEnum.E624.getCode(), ExceptionClaimsCodeEnum.E624.getDescription());
                }
            }

            //4.获取上报异常的店员信息
            Clerk clerk = clerkManager.getClerkByMemberId(seller.getUid());
            Assert.notNull(clerk, "获取店员信息信息异常");

            //5.为异常单实体设置上报初始信息及接单信息
            ExceptionOrderDO exceptionOrderDO = this.initialExceptionOrderDO(exceptionOrderDTO, orderDetailDTO, clerk);

            //6.执行保存ExceptionOrderDO的sql
            this.daoSupport.insert(exceptionOrderDO);
            int exceptionId = this.daoSupport.getLastId("es_exception_order");
            exceptionOrderDO.setExceptionId(exceptionId);
            BeanUtil.copyProperties(exceptionOrderDO, exceptionOrderDTO);
            return Result.success(exceptionOrderDTO);
        } catch (Exception e) {
            logger.error("保存异常单异常", e.getMessage());
            return new Result(ExceptionClaimsCodeEnum.E615.getCode(), e.getMessage());
        }
    }

    //初始化一个ExceptionOrderDO
    private ExceptionOrderDO initialExceptionOrderDO(ExceptionOrderDTO exceptionOrderDTO, OrderDetailDTO orderDetailDTO, Clerk clerk) {
        final String exceptionSnPrefix = "YC";
        ExceptionOrderDO exceptionOrderDO = new ExceptionOrderDO();
        BeanUtil.copyProperties(exceptionOrderDTO, exceptionOrderDO);
        //1.将登录的店员信息作为初始化的异常上报人员和异常单接单人员
        Integer clerkId = clerk.getClerkId();
        exceptionOrderDO.setReciveId(clerkId);
        String clerkName = clerk.getClerkName();
        exceptionOrderDO.setReciveName(clerkName);
        long dateline = DateUtil.getDateline();
        exceptionOrderDO.setReciveTime(dateline);
        exceptionOrderDO.setCreateId(clerkId);
        exceptionOrderDO.setCreateName(clerkName);
        exceptionOrderDO.setCreateTime(dateline);
        exceptionOrderDO.setExceptionStatus(ExceptionStatusEnum.WAITING_PROCESSING.value());
        //2.根据当前时间生成异常单号
        String exceptionSn = exceptionSnPrefix + DateUtil.toString(DateUtil.getDateline(), "yyMMddHHmmss") + (new Random().nextInt(999) + 100);
        exceptionOrderDO.setExceptionSn(exceptionSn);
        //3.查询出买家会员信息-上级团长会员信息-订单自提点信息作为此刻快照保存到异常单
        Member buyer = memberManager.getModel(orderDetailDTO.getMemberId());
        //4.如果查询到买家信息，为异常单设置买家昵称,买家电话初始信息
        if(!ObjectUtils.isEmpty(buyer)){
            exceptionOrderDO.setMemberNickname(buyer.getNickname());
            exceptionOrderDO.setMemberMobile(buyer.getMobile());
        }
        //5.如果上级团长信息不为空，为异常单设置团长初始信息
        Member superiorLeader = distributionManager.getSuperiorLeader(orderDetailDTO.getMemberId());
        if(!ObjectUtils.isEmpty(superiorLeader)){
            exceptionOrderDO.setMemberIdLv1(superiorLeader.getMemberId());
            exceptionOrderDO.setMemberRealnameLv1(superiorLeader.getRealName());
            exceptionOrderDO.setMemberMobileLv1(superiorLeader.getMobile());
        }
        //6.如果订单有自提点ID，为异常单设置自提点初始信息
        Integer leaderId = orderDetailDTO.getLeaderId();
        if(leaderId != null && leaderId >= 0){
            LeaderDO leaderDO = leaderManager.getLeaderDOByLeaderId(leaderId);
            exceptionOrderDO.setSiteLeaderName(leaderDO.getLeaderName());
            exceptionOrderDO.setSiteLeaderMobile(leaderDO.getLeaderMobile());
            exceptionOrderDO.setSiteName(leaderDO.getSiteName());
            exceptionOrderDO.setSiteAddress(leaderDO.getAddress());
        }
        return exceptionOrderDO;
    }

    //订单有效性校验
    private void checkOrderAvailability(OrderDetailDTO orderDetailDTO, Integer sellerId){
        //1.不存在的订单或者不属于当前店铺的订单进行校验
        if (orderDetailDTO == null || !sellerId.equals(orderDetailDTO.getSellerId())) {
            throw new ServiceException(AftersaleErrorCode.E604.name(),  AftersaleErrorCode.E604.describe());
        }
        //2.判断订单是否支付,暂不校验，情况1：用户支付但支付状态未改变，需要上报异常
//        if(orderDetailDTO.getPayStatus().equals(PayStatusEnum.PAY_NO.value())){
//            throw new ServiceException(AftersaleErrorCode.E601.name(),  AftersaleErrorCode.E601.describe() + ",【" +orderDetailDTO.getSn()+ "】订单未支付");
//        }
    }

    @Override
    public Page<ExceptionOrderVO> pageExceptionOrder(ExceptionQueryParamVO exceptionQueryParamVO) {
        StringBuilder sql = new StringBuilder("select e.exception_id,e.exception_sn,e.order_sn,e.exception_status,e.exception_source,")
                .append("e.exception_type,e.exception_description,e.solve_explain,e.solve_types,e.member_score,e.member_comment,")
                .append("e.member_nickname,e.member_mobile,e.member_realname_lv1,e.member_mobile_lv1,e.site_name,e.site_leader_name,")
                .append("e.site_leader_mobile,e.create_time,e.create_name,e.recive_time,e.recive_name,e.process_time,e.process_name,")
                .append("e.complete_time,e.finish_time,e.finish_name,o.order_type,o.shipping_type,o.ship_name,o.ship_mobile,o.ship_addr ")
                .append("from es_exception_order e,es_order o where e.order_sn=o.sn ");
        List<Object> termList = new ArrayList<>();

        //限定登录商户ID
        Integer sellerId = exceptionQueryParamVO.getSellerId();
        Assert.isTrue(sellerId != null && sellerId >= 0, "商户登录ID有误");
        sql.append(" and o.seller_id=? ");
        termList.add(sellerId);

        //时间范围查询
        Long startTime = exceptionQueryParamVO.getStartTime();
        Long endTime = exceptionQueryParamVO.getEndTime();
        String timeType = exceptionQueryParamVO.getTimeType();
        if(startTime != null && startTime > 0){
            Assert.hasText(timeType, "请选择时间类型");
            sql.append(" and e.").append(timeType).append(">=? ");
            termList.add(startTime);
        }
        if(endTime != null && endTime > 0){
            Assert.hasText(timeType, "请选择时间类型");
            sql.append(" and e.").append(timeType).append("<=? ");
            termList.add(endTime);
        }
        //异常号查询
        String exceptionSn = exceptionQueryParamVO.getExceptionSn();
        if(StringUtil.notEmpty(exceptionSn)){
            sql.append(" and e.exception_sn=? ");
            termList.add(exceptionSn);
        }
        //订单号查询
        String orderSn = exceptionQueryParamVO.getOrderSn();
        if(StringUtil.notEmpty(orderSn)){
            sql.append(" and e.order_sn=? ");
            termList.add(orderSn);
        }
        //买家昵称查询
        String memberNickname = exceptionQueryParamVO.getMemberNickname();
        if(StringUtil.notEmpty(memberNickname)){
            sql.append(" and e.member_nickname like ? ");
            termList.add("%" + memberNickname + "%");
        }
        //收货人查询
        String shipName = exceptionQueryParamVO.getShipName();
        if(StringUtil.notEmpty(shipName)){
            sql.append(" and o.ship_name like ? ");
            termList.add("%" + shipName + "%");
        }
        //异常处理状态查询
        String exceptionStatus = exceptionQueryParamVO.getExceptionStatus();
        if(StringUtil.notEmpty(exceptionStatus)){
            sql.append(" and e.exception_status=? ");
            termList.add(exceptionStatus);
        }
        //所属团长真实姓名查询
        String memberRealnameLv1 = exceptionQueryParamVO.getMemberRealnameLv1();
        if(StringUtil.notEmpty(memberRealnameLv1)){
            sql.append(" and e.member_realname_lv1 like ? ");
            termList.add("%" + memberRealnameLv1 + "%");
        }
        //自提点查询
        String siteName = exceptionQueryParamVO.getSiteName();
        if(StringUtil.notEmpty(siteName)){
            sql.append(" and e.site_name=? ");
            termList.add(siteName);
        }
        //收货人电话查询
        String shipMobile = exceptionQueryParamVO.getShipMobile();
        if(StringUtil.notEmpty(shipMobile)){
            sql.append(" and o.ship_mobile=? ");
            termList.add(shipMobile);
        }
        //异常类型查询
        String exceptionType = exceptionQueryParamVO.getExceptionType();
        if(StringUtil.notEmpty(exceptionType)){
            sql.append(" and e.exception_type=? ");
            termList.add(exceptionType);
        }
        //异常上报来源查询
        String exceptionSource = exceptionQueryParamVO.getExceptionSource();
        if(StringUtil.notEmpty(exceptionSource)){
            sql.append(" and e.exception_source=? ");
            termList.add(exceptionSource);
        }
        //按照上报时间倒序排序
        sql.append(" order by e.create_time desc");
        Page page = this.daoSupport.queryForPage(sql.toString(), exceptionQueryParamVO.getPageNo(), exceptionQueryParamVO.getPageSize(),
                ExceptionOrderVO.class, termList.toArray());
//        List<ExceptionOrderVO> exceptionOrderList = page.getData();
//        for (ExceptionOrderVO exceptionOrderVOItem : exceptionOrderList) {
//            //异常类型-订单类型-异常来源-异常状态-订单配送方式
//            exceptionOrderVOItem.setExceptionStatus(ExceptionStatusEnum.valueOf(exceptionOrderVOItem.getExceptionStatus()).getDescription());
//            exceptionOrderVOItem.setExceptionSource(ExceptionSourceEnum.valueOf(exceptionOrderVOItem.getExceptionSource()).getDescription());
//            exceptionOrderVOItem.setExceptionType(ExceptionTypeEnum.valueOf(exceptionOrderVOItem.getExceptionType()).getDescription());
//            String orderType = exceptionOrderVOItem.getOrderType();
//            if(OrderTypeEnum.shetuan.toString().equals(orderType)){
//                exceptionOrderVOItem.setOrderType("社区团购订单");
//            }
//            if(OrderTypeEnum.pintuan.toString().equals(orderType)){
//                exceptionOrderVOItem.setOrderType("拼团订单");
//            }
//            if(OrderTypeEnum.normal.toString().equals(orderType)){
//                exceptionOrderVOItem.setOrderType("普通订单");
//            }
//            exceptionOrderVOItem.setShippingType(ShipTypeEnum.valueOf(exceptionOrderVOItem.getShippingType()).getDesc());
//        }
        return page;
    }

    @Override
    public Result queryExceptionStructVO(Integer exceptionId) {
        try {
            //1.校验此异常单是否可以进行异常处理----规则：a.进行过异常处理的不可以再次处理（每个异常单只能处理1次） b.只有待处理的异常单可以进行处理操作
            ExceptionOrderDO exceptionOrderDO = this.checkAbleProcess(exceptionId);
            //2..查询订单详情
            String orderSn = exceptionOrderDO.getOrderSn();
            OrderDetailDTO orderDetailDTO = this.orderQueryManager.getModel(orderSn);
            Assert.notNull(orderDetailDTO, "订单详情查询错误");
            OrderDetailVO orderDetailVO = new OrderDetailVO();
            BeanUtil.copyProperties(orderDetailDTO, orderDetailVO);
            //3.获取订单sku商品集合
            List<OrderSkuDTO> orderSkuList = orderDetailDTO.getOrderSkuList();
            Assert.notNull(orderSkuList, "订单商品SKU数据查询错误");
            //4.获取订单可退款金额
            double allowRefundPrice = this.orderQueryManager.getOrderRefundPrice(orderSn);
            //5.ExceptionOrderDO 转 ExceptionOrderDTO
            ExceptionOrderVO exceptionOrderVO = new ExceptionOrderVO();
            BeanUtil.copyProperties(exceptionOrderDO, exceptionOrderVO);
            //6、获取售后券信息
            List<CouponDO> couponDOList=claimsManager.getAftersaleCoupon(orderSn);
            //7.组装异常处理展示组合类
            ExceptionStructVO exceptionStructVO = new ExceptionStructVO(exceptionOrderVO, orderDetailVO, orderSkuList, allowRefundPrice,couponDOList);
            return Result.success(exceptionStructVO);
        } catch (Exception e) {
            logger.error("异常处理请求失败", e);
            return new Result(ExceptionClaimsCodeEnum.E615.getCode(), e.getMessage());
        }
    }

    @Override
    public Result batchUpdateExceptionOrderStatus(Integer[] exceptionIds, Seller seller) {
        try {
            //1.参数校验
            Assert.notEmpty(exceptionIds, "异常单Id数组不得为空");
            Assert.notNull(seller, "获取商家登录信息异常");
            //2.校验异常单状态
            List<ExceptionOrderDO> exceptionOrderDOList = this.queryListByIds(exceptionIds);
            for (ExceptionOrderDO exceptionOrderDO : exceptionOrderDOList) {
                String exceptionStatus = exceptionOrderDO.getExceptionStatus();
                String exceptionSn = exceptionOrderDO.getExceptionSn();
                Assert.isTrue(ExceptionStatusEnum.IN_PROCESSING.value().equals(exceptionStatus),
                        "异常单：【" + exceptionSn +"】为" + ExceptionStatusEnum.valueOf(exceptionStatus).getDescription()
                                + "状态，无法进行处理完成操作");
                //3.校验异常对应的理赔单理赔状态是否为 审核失败 | 审核通过 | 已撤销 ，否则无法完成此操作
                List<ClaimsDO> claimsList = this.claimsManager.getClaimsByExceptionId(exceptionOrderDO.getExceptionId());
                if(!CollectionUtils.isEmpty(claimsList)){
                    for (ClaimsDO claimsDO : claimsList) {
                        String claimStatus = claimsDO.getClaimStatus();
                        boolean result = ClaimsStatusEnum.AUDIT_FAIL.value().equals(claimStatus) || ClaimsStatusEnum.AUDIT_SUCCESS.value().equals(claimStatus)
                                || ClaimsStatusEnum.CANCELLED.value().equals(claimStatus);
                        Assert.isTrue(result, "异常单：【" + exceptionSn +"】有未完成的理赔，无法进行处理完成操作");
                    }
                }
            }
            //4.拼接sql值
            String exceptionIdString = StringUtil.implode(",", exceptionIds);
            //5.修改这些异常单的状态为已处理和完成时间
            String sql = "update es_exception_order set exception_status=?, complete_time=? where exception_id in ("
                    + exceptionIdString + ")";
            this.daoSupport.execute(sql, ExceptionStatusEnum.ALREADY_PROCESSED.value(), DateUtil.getDateline());
            return Result.successMessage();
        } catch (Exception e) {
            logger.error("异常处理完成错误", e.getMessage());
            return new Result(ExceptionClaimsCodeEnum.E615.getCode(), e.getMessage());
        }
    }

    @Override
    public List<ExceptionOrderDO> queryListByIds(Integer[] exceptionIds) {
        Assert.notEmpty(exceptionIds, "异常单Ids不得为空");
        String exceptionIdString = StringUtil.implode(",", exceptionIds);
        String sql = "select exception_id,exception_sn,order_sn,exception_status,exception_source,"
                + "exception_type,exception_description,solve_explain,solve_types,member_score,member_comment,member_nickname,"
                + "member_realname_lv1,member_mobile_lv1,site_name,site_leader_name,site_leader_mobile,create_time,create_name,"
                + "recive_time,recive_name,process_time,process_name,complete_time,finish_time,finish_name "
                + "from es_exception_order where exception_id in ("
                + exceptionIdString + ") ";
        return this.daoSupport.queryForList(sql, ExceptionOrderDO.class);
    }

    @Override
    @Transactional(value = "tradeTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result batchCancel(Integer[] exceptionIds, Seller seller) {
        //1.参数校验
        if(ArrayUtils.isEmpty(exceptionIds)){
            throw new ServiceException(ExceptionClaimsCodeEnum.E614.value(), "异常单Id数组不得为空");
        }
        if(ObjectUtils.isEmpty(seller)){
            throw new ServiceException(ExceptionClaimsCodeEnum.E614.value(), "获取商家登录信息异常");
        }
        //2.校验异常状态，已完成和已撤销的无法进行撤销操作
        List<ExceptionOrderDO> exceptionOrderDOList = this.queryListByIds(exceptionIds);
        for (ExceptionOrderDO exceptionOrderDO : exceptionOrderDOList) {
            String exceptionStatus = exceptionOrderDO.getExceptionStatus();
            String exceptionSn = exceptionOrderDO.getExceptionSn();
            if (ExceptionStatusEnum.ALREADY_CANCELED.value().equals(exceptionStatus)
                    || ExceptionStatusEnum.ALREADY_PROCESSED.value().equals(exceptionStatus)) {
                throw new ServiceException(ExceptionClaimsCodeEnum.E617.value(), "异常单：【" + exceptionSn +"】为"
                        + ExceptionStatusEnum.valueOf(exceptionStatus).getDescription() + "状态，无法进行异常撤销");
            }
            //3.校验异常记录对应的理赔单理赔状态，审核已通过的无法进行撤销操作
            List<ClaimsDO> claimsList = claimsManager.getClaimsByExceptionId(exceptionOrderDO.getExceptionId());
            if(!CollectionUtils.isEmpty(claimsList)){
                for (ClaimsDO claimsDO : claimsList) {
                    String claimStatus = claimsDO.getClaimStatus();
                    String claimType=claimsDO.getClaimType();
                    //只有赔付现金和多退少补才判断时候已经审核通过
                    if(claimType.equals(ClaimsTypeEnum.PAYMENT_CASH.value())||claimType.equals(ClaimsTypeEnum.REFUND_CASH.value())){
                        //如果理赔单状态为审核通过或理赔成功，不能撤销理赔单
                        if (claimStatus.equals(ClaimsStatusEnum.AUDIT_SUCCESS.value()) || claimStatus.equals(ClaimsStatusEnum.CLAIM_SUCCESS.value())) {
                            throw new ServiceException(ExceptionClaimsCodeEnum.E618.value(), "异常单：【" + exceptionSn +"】" + ExceptionClaimsCodeEnum.E618.getDescription());
                        }
                    }
                }
            }
        }
        //4.拼接sql参数占位符
        String exceptionIdString = StringUtil.implode(",", exceptionIds);
        //5.批量修改异常单的状态已撤销
        String sql = "update es_exception_order set exception_status='" + ExceptionStatusEnum.ALREADY_CANCELED.value() + "' where exception_id in (" + exceptionIdString + ")";
        this.daoSupport.execute(sql);
        //6.调用理赔业务，批量修改理赔单理赔状态为已撤销
        this.claimsManager.auditClaimsByExcpIds(exceptionIds, seller);
        return Result.successMessage();
    }

    @Override
    public Result batchInsertException(List<ExceptionOrderDTO> insertList, Seller seller) {
        try {
            //1.参数校验
            Assert.notEmpty(insertList, "保存的异常单集合不得为空");
            Assert.notNull(seller, "获取商家登录信息异常");
            //2.获取上报异常的店员信息
            Clerk clerk = clerkManager.getClerkByMemberId(seller.getUid());
            Assert.notNull(clerk, "获取店员信息信息异常");
            List<ExceptionOrderDO> exceptionOrderDOList = new ArrayList<>();
            for (ExceptionOrderDTO exceptionOrderDTO : insertList) {
                //3.获取订单详情并校验订单号
                OrderDetailDTO orderDetailDTO = orderQueryManager.getModel(exceptionOrderDTO.getOrderSn());
                Integer sellerId = seller.getSellerId();
                this.checkOrderAvailability(orderDetailDTO, sellerId);
                //4.为异常单实体设置上报初始信息及接单信息,查询出买家会员信息-上级团长会员信息-订单自提点信息作为此刻快照保存到异常单
                ExceptionOrderDO exceptionOrderDO = this.initialExceptionOrderDO(exceptionOrderDTO, orderDetailDTO, clerk);
                exceptionOrderDOList.add(exceptionOrderDO);
            }
            //5.执行批量保存ExceptionOrderDO的sql
            this.daoSupport.batchInsert("es_exception_order", exceptionOrderDOList);
            return Result.successMessage();
        } catch (Exception e) {
            logger.error("批量上报异常单错误", e.getMessage());
            return new Result(ExceptionClaimsCodeEnum.E615.getCode(), e.getMessage());
        }
    }

    /**
     * 处理异常单后，添加理赔方式，更新
     * 异常单状态，处理人信息，解决说明和解决方式
     */
    @Override
    public void updateSolve(ExceptionOrderDTO exceptionOrderDTO) {
        String sql = "update es_exception_order set exception_status='"+ExceptionStatusEnum.IN_PROCESSING+"',process_id="+exceptionOrderDTO.getProcessId()+
                ",process_name='"+exceptionOrderDTO.getProcessName()+"', process_time="+exceptionOrderDTO.getProcessTime()+",solve_types = '"+exceptionOrderDTO.getSolveTypes()+"'";
        if(StringUtil.notEmpty(exceptionOrderDTO.getSolveExplain())){
            sql = sql.concat(", solve_explain='"+exceptionOrderDTO.getSolveExplain()+"' ");
        }
        sql = sql.concat(" where exception_id=?");
        this.daoSupport.execute(sql, exceptionOrderDTO.getExceptionId());
    }

    @Override
    public Map<String, List<ExceptionEnumStructs>> queryExceptionTypes() {
        ExceptionTypeEnum[] exceptionTypeEnums = ExceptionTypeEnum.values();
        List<ExceptionEnumStructs> structList = new ArrayList<>();
        for (ExceptionTypeEnum exceptionTypeEnum : exceptionTypeEnums) {
            ExceptionEnumStructs exceptionEnumStructs = new ExceptionEnumStructs(exceptionTypeEnum.getDescription(), exceptionTypeEnum.value());
            structList.add(exceptionEnumStructs);
        }
        Map<String, List<ExceptionEnumStructs>> typesMap = new HashMap<>();
        typesMap.put("exceptionTypes", structList);
        return typesMap;
    }

    @Override
    public Map<String, List<ExceptionEnumStructs>> queryExceptionSources() {
        ExceptionSourceEnum[] exceptionSourceEnums = ExceptionSourceEnum.values();
        List<ExceptionEnumStructs> structList = new ArrayList<>();
        for (ExceptionSourceEnum exceptionSourceEnum : exceptionSourceEnums) {
            ExceptionEnumStructs exceptionEnumStructs = new ExceptionEnumStructs(exceptionSourceEnum.getDescription(), exceptionSourceEnum.value());
            structList.add(exceptionEnumStructs);
        }
        Map<String, List<ExceptionEnumStructs>> sourcesMap = new HashMap<>();
        sourcesMap.put("exceptionSources", structList);
        return sourcesMap;
    }

    @Override
    public Map<String, List<ExceptionEnumStructs>> queryExceptionStatus() {
        ExceptionStatusEnum[] exceptionStatusEnums = ExceptionStatusEnum.values();
        List<ExceptionEnumStructs> structList = new ArrayList<>();
        for (ExceptionStatusEnum statusEnum : exceptionStatusEnums) {
            ExceptionEnumStructs exceptionEnumStructs = new ExceptionEnumStructs(statusEnum.getDescription(), statusEnum.value());
            structList.add(exceptionEnumStructs);
        }
        Map<String, List<ExceptionEnumStructs>> statusMap = new HashMap<>();
        statusMap.put("exceptionStatus", structList);
        return statusMap;
    }

    @Override
    public Map<String, List<ExceptionEnumStructs>> queryExceptionTimeType() {
        ExceptionQueryTimeEnum[] queryTimeEnums = ExceptionQueryTimeEnum.values();
        List<ExceptionEnumStructs> structList = new ArrayList<>();
        for (ExceptionQueryTimeEnum queryTimeEnum : queryTimeEnums) {
            ExceptionEnumStructs exceptionEnumStructs = new ExceptionEnumStructs(queryTimeEnum.getDescription(), queryTimeEnum.value());
            structList.add(exceptionEnumStructs);
        }
        Map<String, List<ExceptionEnumStructs>> statusMap = new HashMap<>();
        statusMap.put("exceptionTimeType", structList);
        return statusMap;
    }

    @Override
    public ExceptionOrderDO checkAbleProcess(Integer exceptionId) {
        //1.查询异常单信息
        if(exceptionId == null){
            throw new ServiceException(ExceptionClaimsCodeEnum.E614.value(), "请求参数异常单ID有误");
        }
        ExceptionOrderDO exceptionOrderDO = this.daoSupport.queryForObject(ExceptionOrderDO.class, exceptionId);
        if(exceptionOrderDO == null){
            throw new ServiceException(ExceptionClaimsCodeEnum.E615.value(), "异常单信息不存在");
        }
        if(!ExceptionStatusEnum.WAITING_PROCESSING.value().equals(exceptionOrderDO.getExceptionStatus())){
            throw new ServiceException(ExceptionClaimsCodeEnum.E615.value(), "只有待处理状态的异常单可进行处理操作");
        }
        //2.校验此异常是否进行过理赔，每条异常单只能生成一次理赔单，但每个订单可以重复生成异常单
        List<ClaimsDO> claimsList = this.claimsManager.getClaimsByExceptionId(exceptionId);
        if(!CollectionUtils.isEmpty(claimsList)){
            throw new ServiceException(ExceptionClaimsCodeEnum.E615.value(), "此异常单已进行过异常处理，如需继续处理，请为此订单生成新异常单");
        }
        return exceptionOrderDO;
    }

    @Override
    public String getAfterSaleTemplate(MessageCodeEnum messageCodeEnum, String orderSn) {
        MessageTemplateDO messageTemplateDO = messageTemplateManager.getModel(messageCodeEnum);
        String smsContent = messageTemplateDO.getSmsContent();
        if(StringUtil.notEmpty(smsContent)){
            Map<String, Object> valueMap = new HashMap<>();
            valueMap.put("orderSn", orderSn);
            smsContent = messageTemplateManager.replaceContent(smsContent, valueMap);
        }
        return smsContent;
    }
}
